#ifndef OS_ELF_H
#define OS_ELF_H

#include "types.h"

// ELF相关数据类型
typedef uint32_t Elf32_Addr;
typedef uint16_t Elf32_Half;
typedef uint32_t Elf32_Off;
typedef uint32_t Elf32_Sword;
typedef uint32_t Elf32_Word;

#pragma pack(1)

// ELF Header
#define EI_NIDENT 16
#define ELF_MAGIC 0x7F

typedef struct
{
    char e_ident[EI_NIDENT]; // ELF标识数组（魔数+文件属性）
    Elf32_Half e_type;       // 文件类型（可执行/目标文件/共享库）
    Elf32_Half e_machine;    // 目标架构（如x86、ARM）
    Elf32_Word e_version;    // ELF版本
    Elf32_Addr e_entry;      // 程序入口地址（加载后CPU从这里执行）
    Elf32_Off e_phoff;       // 程序头表在文件中的偏移量
    Elf32_Off e_shoff;       // 节头表在文件中的偏移量（加载器用不到）
    Elf32_Word e_flags;      // 处理器相关标志
    Elf32_Half e_ehsize;     // ELF文件头的大小
    Elf32_Half e_phentsize;  // 每个程序头表项的大小
    Elf32_Half e_phnum;      // 程序头表项的数量
    Elf32_Half e_shentsize;  // 每个节头表项的大小（加载器用不到）
    Elf32_Half e_shnum;      // 节头表项的数量（加载器用不到）
    Elf32_Half e_shstrndx;   // 节名字符串表的索引（加载器用不到）
} Elf32_Ehdr;

#define PT_LOAD 1 // 表示该程序头项是「可加载段」

typedef struct
{
    Elf32_Word p_type;   // 段类型（仅处理PT_LOAD=1的可加载段）
    Elf32_Off p_offset;  // 该段在ELF文件中的偏移量
    Elf32_Addr p_vaddr;  // 段的虚拟地址（分页开启后用）
    Elf32_Addr p_paddr;  // 段的物理地址（分页未开启时用）
    Elf32_Word p_filesz; // 段在ELF文件中的实际大小（已初始化数据）
    Elf32_Word p_memsz;  // 段在内存中需要的总大小（含未初始化数据）
    Elf32_Word p_flags;  // 段的权限（读/写/执行）
    Elf32_Word p_align;  // 段的内存对齐要求
} Elf32_Phdr;

#pragma pack()

#endif // OS_ELF_H